package org.example.JavaPoet;

import com.google.common.base.Preconditions;
import com.squareup.javapoet.*;

import javax.lang.model.element.Modifier;
import java.io.IOException;

public class JavaPoetTest {
    public static void main(String[] arg) {
        // 创建类名
        String packageName = JavaPoetTest.class.getPackage().getName();
        String classNameStr = "PersonGenerated";
        ClassName className = ClassName.get(packageName, classNameStr);

        // 声明成员变量
        String name = "name";
        String age = "age";
        FieldSpec nameField = FieldSpec.builder(String.class, name, Modifier.PRIVATE).build();
        FieldSpec ageField = FieldSpec.builder(TypeName.INT, age, Modifier.PRIVATE).build();

        // 声明构造方法
        MethodSpec construct1 = MethodSpec.constructorBuilder().build();
        MethodSpec construct2 = MethodSpec.constructorBuilder()
                .addParameter(TypeName.INT, age)
                // $T传入的类经过JavaFile编译后，最后会在源码中加入import语句，原位置剩下类名
                .addStatement("$T.checkArgument($S, \"age must be greater than 0\")", Preconditions.class, age) // 测试引入其他包
                // 与直接传入age一样，FieldSpec的toString()方法，最终返回的是字段名
                .addStatement("this.$1N = $1N", ageField)
                .build();

        // 声明方法
        MethodSpec setName = MethodSpec.methodBuilder("setName")
                .addModifiers(Modifier.PUBLIC)
                .returns(TypeName.VOID)
                .addParameter(TypeName.get(String.class), name)
                .addStatement("this.$N = $N", name, name) // 等价于 .addStatement("this.$1N = $1N", name)
                .build();
        MethodSpec setAge = MethodSpec.methodBuilder("getAge")
                .addModifiers(Modifier.PUBLIC)
                .returns(TypeName.INT)
                .addParameter(TypeName.INT, age)
                .addStatement("return $N", age)
                .build();

        // 声明类
        TypeSpec typeSpec = TypeSpec.classBuilder(className)
                .addModifiers(Modifier.PUBLIC)
                .addField(nameField)
                .addField(ageField)
                .addMethod(construct1)
                .addMethod(construct2)
                .addMethod(setName)
                .addMethod(setAge)
                .build();

        // 打印创建的类，不会自动添加包名、import等信息
        System.out.println(typeSpec);
    }
}

